<?php

/**
 * HTML安全过滤&清理
 *
 * @author suning <snsnsky@gmail.com>
 *
 * $Id$
 */

namespace Safe;

require(BASEPATH_LIBRARY . 'purifier/HTMLPurifier.standalone.php');

class HTMLClean
{
    /*
     * 默认配置
     */
    const CONFIG_DEFAULT = 0;

    /**
     * 导入第三方文章
     */
    const CONFIG_IMPORT_ARTICLE = 1;

    /*
     * 配置缓存路径
     */
    private $cache_dir = '';

    /*
     * 过滤器配置数据
     */
    private $config = null;

    /**
     * 过滤对象
     *
     * @var \HTMLPurifier
     */
    private $purifier = null;

    public function __construct($mode = self::CONFIG_DEFAULT)
    {
        global $app;
        $this->cache_dir = $app->cfg['path']['cache'] . 'HTMLPurifier';
        $this->config = $this->createConfig($mode);
        $this->purifier = new \HTMLPurifier($this->config);
    }

    /**
     * 过滤一段html
     *
     * @param string     $html   需要过滤的内容
     * @param int|object $config HTMLPurifier_Config生成的配置数据，也可以直接为配置常量
     *
     * @return string
     */
    public function purify($html, $config = null)
    {
        if ($config !== null && !($config instanceof \HTMLPurifier_Config)) {
            $config = $this->createConfig($config);
        }

        return $this->purifier->purify($html, $config);
    }

    /**
     * 创建一个新的配置文件
     *
     * @param integer $mode 配置文件模式 使用常量
     * @return \HTMLPurifier_Config
     */
    public function createConfig($mode = self::CONFIG_DEFAULT)
    {
        $config = \HTMLPurifier_Config::createDefault();
        // 设置缓存路径
        $config->set('Cache.SerializerPath', $this->cache_dir);
        if (!is_dir($this->cache_dir)) {
            mkdir($this->cache_dir, 0755, true);
        }

        switch ($mode) {
            case self::CONFIG_IMPORT_ARTICLE:
                $config->set('HTML.Doctype', 'HTML 4.01 Transitional');
                $config->set('Attr.AllowedClasses', null);
                $config->set('Attr.DefaultImageAlt', '');
                $config->set('CSS.AllowedProperties', null);
                $config->set('HTML.Allowed', 'table[border|width],tbody,tr,td,th,img[src|alt|data-height|data-width],span,p,ul,ol,li,strong,em,sup,sub,b,div,section,blockquote,pre,small,article');
                $config->set('HTML.DefinitionID', 'html5-definitions');
                $config->set('HTML.DefinitionRev', 1);
                $config->set('AutoFormat.RemoveEmpty', true);
                if ($def = $config->maybeGetRawHTMLDefinition()) {
                    $def->addElement('section', 'Block', 'Flow', 'Common');
                    $def->addElement('article', 'Block', 'Flow', 'Common');
                    $def->addAttribute('img', 'data-height', 'Length');
                    $def->addAttribute('img', 'data-width', 'Length');
                }

                break;
            case self::CONFIG_DEFAULT:
            default:
                $config->set('HTML.Doctype', 'XHTML 1.0 Transitional');
                $config->set('Attr.AllowedClasses', []);
                $config->set('Attr.AllowedFrameTargets', ['_blank' => true, '_self' => true]);
                break;
        }

        return $config;
    }
}